# WebGPU Batch Rendering Framework
# CMake configuration for building the C++ components

cmake_minimum_required(VERSION 3.16)
project(WebGPUBatchRender VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Options
option(BUILD_TESTS "Build unit tests" ON)
option(BUILD_EXAMPLES "Build examples" ON)
option(ENABLE_VALIDATION "Enable WebGPU validation layers" OFF)

# Find packages
find_package(PkgConfig REQUIRED)

# Dawn/WebGPU
find_path(DAWN_INCLUDE_DIR dawn/webgpu_cpp.h
    HINTS 
        ${DAWN_ROOT}/include
        ${DAWN_ROOT}/out/Release/gen/include
        /usr/local/include
        /opt/dawn/include
)

find_library(DAWN_NATIVE_LIB
    NAMES dawn_native libdawn_native
    HINTS
        ${DAWN_ROOT}/out/Release
        ${DAWN_ROOT}/out/Debug
        /usr/local/lib
        /opt/dawn/lib
)

find_library(DAWN_PROC_LIB
    NAMES dawn_proc libdawn_proc
    HINTS
        ${DAWN_ROOT}/out/Release
        ${DAWN_ROOT}/out/Debug
        /usr/local/lib
        /opt/dawn/lib
)

if(NOT DAWN_INCLUDE_DIR OR NOT DAWN_NATIVE_LIB OR NOT DAWN_PROC_LIB)
    message(FATAL_ERROR "Dawn WebGPU libraries not found. Please set DAWN_ROOT environment variable.")
endif()

# Include directories
include_directories(${DAWN_INCLUDE_DIR})
include_directories(src)

# Compiler flags
if(MSVC)
    add_compile_options(/W4)
    add_definitions(-D_CRT_SECURE_NO_WARNINGS)
else()
    add_compile_options(-Wall -Wextra -Wpedantic)
endif()

if(ENABLE_VALIDATION)
    add_definitions(-DENABLE_WEBGPU_VALIDATION)
endif()

# Source files
set(WEBGPU_BATCH_SOURCES
    src/cpp/dawn_batch_processor.cpp
    src/bindings/webgpu_batch_bindings.cpp
)

set(WEBGPU_BATCH_HEADERS
    src/cpp/dawn_batch_processor.h
    src/bindings/webgpu_batch_bindings.h
)

# Main library
add_library(webgpu_batch STATIC ${WEBGPU_BATCH_SOURCES} ${WEBGPU_BATCH_HEADERS})

target_link_libraries(webgpu_batch 
    ${DAWN_NATIVE_LIB} 
    ${DAWN_PROC_LIB}
)

# Platform-specific libraries
if(WIN32)
    target_link_libraries(webgpu_batch d3d12 dxgi dxguid)
elseif(APPLE)
    find_library(METAL_LIBRARY Metal)
    find_library(FOUNDATION_LIBRARY Foundation)
    find_library(QUARTZCORE_LIBRARY QuartzCore)
    target_link_libraries(webgpu_batch ${METAL_LIBRARY} ${FOUNDATION_LIBRARY} ${QUARTZCORE_LIBRARY})
elseif(UNIX)
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(X11 REQUIRED x11)
    target_link_libraries(webgpu_batch ${X11_LIBRARIES})
endif()

# Threading support
find_package(Threads REQUIRED)
target_link_libraries(webgpu_batch Threads::Threads)

# Install targets
install(TARGETS webgpu_batch
    ARCHIVE DESTINATION lib
    LIBRARY DESTINATION lib
    RUNTIME DESTINATION bin
)

install(FILES ${WEBGPU_BATCH_HEADERS}
    DESTINATION include/webgpu_batch
)

# Build tests
if(BUILD_TESTS)
    # Find Google Test
    find_package(GTest)
    if(NOT GTest_FOUND)
        # Download and build Google Test
        include(FetchContent)
        FetchContent_Declare(
            googletest
            URL https://github.com/google/googletest/archive/03597a01ee50ed33e9fd7188f06be875baedd114.zip
        )
        FetchContent_MakeAvailable(googletest)
    endif()
    
    # Test executable
    add_executable(webgpu_batch_test
        tests/webgpu_batch_test.cpp
    )
    
    target_link_libraries(webgpu_batch_test
        webgpu_batch
        gtest_main
        gmock_main
    )
    
    # Enable testing
    enable_testing()
    add_test(NAME WebGPUBatchTests COMMAND webgpu_batch_test)
    
    # Custom test target
    add_custom_target(test_webgpu_batch
        COMMAND ${CMAKE_CTEST_COMMAND} --verbose
        DEPENDS webgpu_batch_test
    )
endif()

# Build examples (if enabled)
if(BUILD_EXAMPLES)
    # C++ example
    add_executable(webgpu_batch_example
        examples/cpp_example.cpp
    )
    
    target_link_libraries(webgpu_batch_example webgpu_batch)
endif()

# Documentation target
find_package(Doxygen)
if(DOXYGEN_FOUND)
    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in
                   ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
    
    add_custom_target(docs
        ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
        COMMENT "Generating API documentation with Doxygen" VERBATIM
    )
endif()

# Package configuration
set(CPACK_PACKAGE_NAME "WebGPU-Batch-Render")
set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "WebGPU Batch Rendering Framework")
set(CPACK_PACKAGE_VENDOR "WeChat Team")

if(WIN32)
    set(CPACK_GENERATOR "ZIP")
else()
    set(CPACK_GENERATOR "TGZ")
endif()

include(CPack)

# Print build information
message(STATUS "WebGPU Batch Render Build Configuration:")
message(STATUS "  Version: ${PROJECT_VERSION}")
message(STATUS "  Build Tests: ${BUILD_TESTS}")
message(STATUS "  Build Examples: ${BUILD_EXAMPLES}")
message(STATUS "  Enable Validation: ${ENABLE_VALIDATION}")
message(STATUS "  Dawn Include Dir: ${DAWN_INCLUDE_DIR}")
message(STATUS "  Dawn Native Lib: ${DAWN_NATIVE_LIB}")
message(STATUS "  Dawn Proc Lib: ${DAWN_PROC_LIB}")
message(STATUS "  C++ Standard: ${CMAKE_CXX_STANDARD}")
message(STATUS "  Build Type: ${CMAKE_BUILD_TYPE}")

# Add custom clean target
add_custom_target(clean-all
    COMMAND ${CMAKE_BUILD_TOOL} clean
    COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/CMakeFiles
    COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/CMakeCache.txt
    COMMENT "Cleaning all build artifacts"
)